////////////////////////////////////////////////////////////////////////////
//
//  Crytek Engine Source File.
//  Shader extension
//  Copyright (C), Crytek Studios, 2001-2004.
// -------------------------------------------------------------------------
//  File name:   CommonGlowPass.cfi
//  Version:     v1.00
//  Created:     23/11/2004 by Tiago Sousa
//  Compilers:   
//  Description: Common/Shared passes bettwen shaders. Should be included after
//    main shader technique
//
//  NOTE: ALWAYS MAKE SURE VERTEX INPUTS MATCH CORRECTLY BEFORE INCLUDING THIS!
//  TODO: Add support for texture modifiers, since Illum and others require it
//  "Common_" name convention - for shader sharing in cache files
//
//
// -------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////

/// Un-Tweakables ////////////////////// 
// xyz = glow intensity/color, alpha is glow size

float4 GlowParams : PB_GlowParams;

sampler2D glowDiffuseMapSampler : register (s0) 
{ 
  Texture = $Diffuse; 
  sRGBLookup = false; 
};

sampler2D glowDiffuseMapSampler_Decal
{ 
	Texture = $Diffuse; 	
	AddressU = Border;
	AddressV = Border;
	BorderColor = {0, 0, 0, 0};	
  sRGBLookup = false; 
};

sampler2D glowDecalMapSampler = sampler_state 
{ 
  Texture = $DecalOverlay; 
};

////////////////////////////////////////////////////////
//                Glow PASS
////////////////////////////////////////////////////////

///////////////// vertex input/output //////////////////
struct vert2fragGlow
{
#if _DS || _PS || !VS_TESSELLATION || _RT_NO_TESSELLATION
	OUT_P
#endif

#if !_PS && !_DS && VS_TESSELLATION && !_RT_NO_TESSELLATION
	float4 vView     : TEXCOORDN;
	half4 vNormal    : TEXCOORDN;
#endif

  float4 baseTC     : TEXCOORDN;
  float4 maskTC     : TEXCOORDN;

#if %_RT_DECAL_TEXGEN_2D
  float3 DistAtten : TEXCOORDN;
#endif 

#if %VERTCOLORS
  float3 Color	: COLOR0;
#endif

};

///////////////// vertex shaders //////////////////
vert2fragGlow Common_GlowPassVS(app2vertGlow IN)
{
  vert2fragGlow OUT = (vert2fragGlow)0;
  
  VSVertexContext vertPassPos = (VSVertexContext)0;
  streamPos_FromGlow(IN, vertPassPos);

  float4 HPosition = Pos_VS_General(g_VS_ViewProjZeroMatr, vertPassPos);

#if VS_TESSELLATION && !_RT_NO_TESSELLATION
	//relative possition
	OUT.vView.xyz = vertPassPos.WorldPos.xyz;
	OUT.vNormal.xyz = normalize(mul((const float3x3)vertPassPos.InstMatrix, vertPassPos.Normal.xyz));
#else
	OUT.HPosition = HPosition;
#endif
  
  float4 baseTC = vertPassPos.baseTC;
#if %_RT_DECAL_TEXGEN_2D
	_TCModifyDecal( vertPassPos, baseTC, OUT.DistAtten );
#endif

  // reminder for Andrey, texture modifiers should work on all cases
  _TCModify(baseTC, OUT.baseTC, vertPassPos.Position, vertPassPos.ObjToTangentSpace[2], TS_DIFFUSE);

  //OUT.baseTC = _TCModify(baseTC, vPos, vNorm, _TCMMatrixDif, _TCGMatrixDif, true, false, 0);
  OUT.maskTC.xyzw = mul(baseTC, _TCMMatrixDecal);
  
  float fAlphaRef = 0.01;

  OUT.maskTC.z = saturate( fAlphaRef );

  float fAlpha = AmbientOp.w;
#if _RT_INSTANCING_ATTR || _RT_INSTANCING_CONST
  fAlpha = IN.InstAmbientOp.w;
#endif

  OUT.maskTC.w = fAlpha;

#if %VERTCOLORS
  OUT.Color.xyz = vertPassPos.Color.xyz;
  OUT.maskTC.w *= vertPassPos.Color.w;
#endif

  return OUT;            
}

///////////////// pixel shaders //////////////////
pixout Common_GlowPassPS(vert2fragGlow IN)
{
  pixout OUT = (pixout)0;  

  half4 baseColor = tex2D(glowDiffuseMapSampler, IN.baseTC.xy);
  half4 maskColor = 1;
  
   // Load the diffuse texture
#if %DECAL && %_RT_DECAL_TEXGEN_2D
  #if %_TT0_TCPROJ
    baseColor = tex2Dproj(glowDiffuseMapSampler_Decal, IN.baseTC.xyzw);
  #else
    baseColor = GetTexture2D(glowDiffuseMapSampler_Decal, IN.baseTC.xy);
  #endif
#else

  maskColor = tex2D(glowDecalMapSampler, IN.maskTC.xy);  

#endif

  // note for x360 we should patch texture header/restore after to remove gamma reads

  // Apply mask
  baseColor *= maskColor;

  OUT.Color = (half4)GlowParams * baseColor;  
  OUT.Color.xyz *= (half3) MatDifColor;
  OUT.Color.xyz *= baseColor.w * IN.maskTC.w;

#if %VERTCOLORS
  OUT.Color.xyz *= IN.Color.xyz;
#endif

//if %_RT_DECAL_TEXGEN_3D
//  OUT.Color.xyz *= saturate(1 - IN.DistAtten.x * IN.DistAtten.x) * IN.DistAtten.y;
//elif %_RT_DECAL_TEXGEN_2D
//  OUT.Color.xyz *= saturate(1 - dot(IN.DistAtten, IN.DistAtten));
//endif

  
  // Re-scale range
  OUT.Color.xyz *= PS_HDR_RANGE_ADAPT_MAX;
  OUT.Color.w = 1.0;
    
  return OUT;
}

//////////////////////////////// technique ////////////////

#include "CommonGlowPassTess.cfi"


technique GlowPass
{
  pass p0
  {
    VertexShader = Common_GlowPassVS() GlowVS;
#ifdef VS_TESSELLATION
	HullShader   = Common_GlowPassHS() GeneralHS;
	DomainShader = Common_GlowPassDS() GeneralDS;
#endif
    PixelShader = Common_GlowPassPS() GlowPS;

    ZEnable = true;
    ZWriteEnable = false;
    CullMode = Back;
    IgnoreMaterialState = true;

#if %DECAL
    ZFunc = LEqual;    
#endif

    AlphaBlendEnable = true;
    SrcBlend = ONE;
    DestBlend = ONE;        
    ZFunc = LEqual;    

  }
}
